package com.liaoye.hellocustomview;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;

import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.Keyframe;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Shader;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.AnimationDrawable;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.Spannable;
import android.text.SpannableString;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.BounceInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.liaoye.hellocustomview.evaluator.CharEvaluator;
import com.liaoye.hellocustomview.evaluator.FallingBallEvaluator;
import com.liaoye.hellocustomview.model.Point;
import com.liaoye.hellocustomview.util.BitmapUtil;
import com.liaoye.hellocustomview.util.DPUtil;
import com.liaoye.hellocustomview.util.FileUtil;
import com.liaoye.hellocustomview.view.AnimaWaveView;
import com.liaoye.hellocustomview.view.AvatarView;
import com.liaoye.hellocustomview.view.AvatorView;
import com.liaoye.hellocustomview.view.BallTextView;
import com.liaoye.hellocustomview.view.BitMapCreateView;
import com.liaoye.hellocustomview.view.BitMapView;
import com.liaoye.hellocustomview.view.BitmapShaderView;
import com.liaoye.hellocustomview.view.BitmapShadowView;
import com.liaoye.hellocustomview.view.BlurMaskFilterView;
import com.liaoye.hellocustomview.view.CameraPreSurfaceView;
import com.liaoye.hellocustomview.view.ClipRgnView;
import com.liaoye.hellocustomview.view.DashBoardView;
import com.liaoye.hellocustomview.view.MutableForegroundColorSpan;
import com.liaoye.hellocustomview.view.MyTextView;
import com.liaoye.hellocustomview.view.NormalGestureTrackView;
import com.liaoye.hellocustomview.view.PaintView;
import com.liaoye.hellocustomview.view.PaintView2;
import com.liaoye.hellocustomview.view.PaintView3;
import com.liaoye.hellocustomview.view.PathGetLoadingView;
import com.liaoye.hellocustomview.view.PathGetSegmentView;
import com.liaoye.hellocustomview.view.PathGetTanView;
import com.liaoye.hellocustomview.view.PathMeasureView;
import com.liaoye.hellocustomview.view.PathView;
import com.liaoye.hellocustomview.view.PieView;
import com.liaoye.hellocustomview.view.RadialGradientView;
import com.liaoye.hellocustomview.view.RectPointView;
import com.liaoye.hellocustomview.view.SpiderView;
import com.liaoye.hellocustomview.view.TelescopeView;
import com.liaoye.hellocustomview.view.TypefaceView;

import java.io.File;
import java.io.FileOutputStream;

public class CustomViewActivity extends AppCompatActivity {
    private static final String TAG = CustomViewActivity.class.getSimpleName();
    private LinearLayout mLlCustom;
    private int position;

    private boolean mIsOpenMenu = false;
    private ImageView menu;
    private ImageView item1;
    private ImageView item2;
    private ImageView item3;
    private ImageView item4;
    private ImageView item5;
    private boolean mIsCapture;

    private int i;
    private WindowManager mWindowManager;
    private ImageView mWindowImageView;
    private int mLastX;
    private int mLastY;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom);

        mLlCustom = findViewById(R.id.ll_custom);

        Intent intent = getIntent();
        String title = intent.getStringExtra("title");
        position = intent.getIntExtra("position", 0);
        setTitle(title);

        initLayout();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 100) {
            boolean isAllGranted = true;
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    isAllGranted = false;
                }
            }
            Log.i(TAG, "onRequestPermissionsResult: " + isAllGranted);
            if (isAllGranted) {
                View childView = mLlCustom.getChildAt(0);
                if (childView != null) {
                    FrameLayout previewLayout = childView.findViewById(R.id.camera_preview);
                    CameraPreSurfaceView mCameraSurfaceView = new CameraPreSurfaceView(this);
                    previewLayout.addView(mCameraSurfaceView);
                    Button btnSwitch = childView.findViewById(R.id.button_switch);
                    Button buttonCapture = childView.findViewById(R.id.button_capture);
                    Button buttonTake = childView.findViewById(R.id.button_take);
                    btnSwitch.setOnClickListener(v -> {
                        if (mIsCapture) {
                            Toast.makeText(this, "请先停止录制视频", Toast.LENGTH_LONG).show();
                            return;
                        }
                        mCameraSurfaceView.switchCamera();
                    });
                    buttonTake.setOnClickListener(v -> {
                        if (mIsCapture) {
                            Toast.makeText(this, "请先停止录制视频", Toast.LENGTH_LONG).show();
                            return;
                        }
                        mCameraSurfaceView.takePicture();
                    });
                    buttonCapture.setOnClickListener(v -> {
                        if (mIsCapture) {
                            mCameraSurfaceView.releaseMediaRecorder();
                            buttonCapture.setText("开始录制");
                        } else {
                            mIsCapture = mCameraSurfaceView.capture();
                            if (mIsCapture) {
                                buttonCapture.setText("停止录制");
                            }
                        }
                    });
                }
            } else {
                requestPermission();
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 200){
            addWindowAlert();
        }
    }

    private void requestPermission() {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, 100);
    }

    private void requestWindowPermission() {
        if(Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) {
            Intent mIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            startActivityForResult(mIntent, 200);
        } else {
            addWindowAlert();
        }
    }


    private void initLayout() {
        View childView = null;
        switch (position) {
            case 0:
                childView = new PaintView(this);
                break;
            case 1:
                childView = new PathView(this);
                break;
            case 2:
                childView = new RectPointView(this);
                break;
            case 3:
                childView = new SpiderView(this);
                break;
            case 4:
                childView = new TypefaceView(this);
                break;
            case 5:
                childView = new AvatarView(this);
                break;
            case 6:
                childView = new ClipRgnView(this);
                break;
            case 7:
            case 8:
            case 9:
            case 10:
            case 11:
            case 12:
                childView = LayoutInflater.from(this).inflate(R.layout.item_animate, mLlCustom, false);
                initAnimateView(childView);
                break;
            case 13:
                childView = LayoutInflater.from(this).inflate(R.layout.item_splash, mLlCustom, false);
                initSplashView(childView);
                break;
            case 14:
                childView = LayoutInflater.from(this).inflate(R.layout.item_loading, mLlCustom, false);
                initLoadingView(childView);
                break;
            case 15:
                childView = LayoutInflater.from(this).inflate(R.layout.item_scanner, mLlCustom, false);
                initScannerView(childView);
                break;
            case 16:
                childView = LayoutInflater.from(this).inflate(R.layout.item_frame, mLlCustom, false);
                initFrameView(childView);
                break;
            case 17:
                childView = LayoutInflater.from(this).inflate(R.layout.item_animate, mLlCustom, false);
                initValueAnimateView(childView);
                break;
            case 18:
                childView = LayoutInflater.from(this).inflate(R.layout.item_loading_image, mLlCustom, false);
                break;
            case 19:
                childView = LayoutInflater.from(this).inflate(R.layout.item_ball, mLlCustom, false);
                initBallView(childView);
                break;
            case 20:
                childView = LayoutInflater.from(this).inflate(R.layout.item_animate, mLlCustom, false);
                initObjectAnimateView(childView);
                break;
            case 21:
                childView = LayoutInflater.from(this).inflate(R.layout.item_ball_object, mLlCustom, false);
                initObjectBallView(childView);
                break;
            case 22:
                childView = LayoutInflater.from(this).inflate(R.layout.item_animate_set, mLlCustom, false);
                initAnimateSetView(childView);
                break;
            case 23:
                childView = LayoutInflater.from(this).inflate(R.layout.item_menu, mLlCustom, false);
                initMenuView(childView);
                break;
            case 24:
            case 25:
                childView = LayoutInflater.from(this).inflate(R.layout.item_animate, mLlCustom, false);
                initValueAnimatorView(childView);
                break;
            case 26:
            case 27:
                childView = LayoutInflater.from(this).inflate(R.layout.item_property, mLlCustom, false);
                initPropertyValuesHolder(childView);
                break;
            case 28:
                childView = LayoutInflater.from(this).inflate(R.layout.item_surface, mLlCustom, false);
                break;
            case 29:
                childView = LayoutInflater.from(this).inflate(R.layout.item_animation_surface, mLlCustom, false);
                break;
            case 30:
                childView = LayoutInflater.from(this).inflate(R.layout.item_double_buffering_surface, mLlCustom, false);
                break;
            case 31:
                childView = LayoutInflater.from(this).inflate(R.layout.item_react_refresh_surface, mLlCustom, false);
                break;
            case 32:
                childView = LayoutInflater.from(this).inflate(R.layout.item_camera_surface, mLlCustom, false);
                requestPermission();
                break;
            case 33:
                childView = LayoutInflater.from(this).inflate(R.layout.item_keyframe, mLlCustom, false);
                initKeyFrameView(childView);
                break;
            case 34:
                childView = LayoutInflater.from(this).inflate(R.layout.item_animate_layout_changes, mLlCustom, false);
                initAnimateLayoutChanges(childView);
                break;
            case 35:
                childView = LayoutInflater.from(this).inflate(R.layout.item_layout_transition, mLlCustom, false);
                initLayoutTransition(childView);
                break;
            case 36:
                childView = new PathMeasureView(this);
                break;
            case 37:
                childView = LayoutInflater.from(this).inflate(R.layout.item_layout_foreground_color_span, mLlCustom, false);
                initForegroundColorView(childView);
                break;
            case 38:
                childView = new PathGetSegmentView(this);
                break;
            case 39:
                childView = new PathGetTanView(this);
                break;
            case 40:
                childView = new PathGetLoadingView(this);
                break;
            case 41:
            case 42:
                childView = LayoutInflater.from(this).inflate(R.layout.item_svg_line, mLlCustom, false);
                initVectorLine(childView);
                break;
            case 43:
                childView = new PaintView2(this);
                break;
            case 44:
                childView = new PaintView3(this);
                break;
            case 45:
                childView = new NormalGestureTrackView(this);
                break;
            case 46:
                childView = new AnimaWaveView(this);
                break;
            case 47:
                childView = new BlurMaskFilterView(this);
                break;
            case 48:
                childView = new BitmapShadowView(this);
                break;
            case 49:
                childView = LayoutInflater.from(this).inflate(R.layout.item_bitmap_shader, mLlCustom, false);
                initBitmapShaderView(childView);
                break;
            case 50:
                childView = new TelescopeView(this);
                break;
            case 51:
                childView = new AvatorView(this);
                break;
            case 52:
                childView = LayoutInflater.from(this).inflate(R.layout.item_linear_gradient, mLlCustom, false);
                break;
            case 53:
                childView = LayoutInflater.from(this).inflate(R.layout.item_shimmer_text, mLlCustom, false);
                break;
            case 54:
                childView = new RadialGradientView(this);
                break;
            case 55:
                childView = new BitMapView(this);
                break;
            case 56:
                childView = LayoutInflater.from(this).inflate(R.layout.item_bm, mLlCustom, false);
                initBMView(childView);
                break;
            case 57:
                childView = new BitMapCreateView(this);
                break;
            case 58:
                childView = LayoutInflater.from(this).inflate(R.layout.item_stoke_bg, mLlCustom, false);
                break;
            case 59:
                childView = LayoutInflater.from(this).inflate(R.layout.item_watermark, mLlCustom, false);
                break;
            case 60:
                childView = LayoutInflater.from(this).inflate(R.layout.item_custom_text, mLlCustom, false);
                break;
            case 61:
                childView = LayoutInflater.from(this).inflate(R.layout.item_my_linearlayout, mLlCustom, false);
                break;
            case 62:
                childView = LayoutInflater.from(this).inflate(R.layout.item_flow_layout, mLlCustom, false);
                break;
            case 63:
                childView = new DashBoardView(this);
                break;
            case 64:
                childView = new PieView(this);
                break;
            case 65:
                childView = LayoutInflater.from(this).inflate(R.layout.item_gesturedetector, mLlCustom, false);
                break;
            case 66:
                childView = LayoutInflater.from(this).inflate(R.layout.item_window, mLlCustom, false);
                initWindow(childView);
                break;
            default:
                break;
        }
        if (childView != null) {
            mLlCustom.addView(childView);
        }
    }

    private void initWindow(View childView) {
        mWindowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
        Button btnAdd = childView.findViewById(R.id.btn_add);
        Button btnRemove = childView.findViewById(R.id.btn_remove);
        btnAdd.setOnClickListener(v -> {
            requestWindowPermission();
        });
        btnRemove.setOnClickListener(v -> {
            if(mWindowImageView != null) {
                mWindowManager.removeViewImmediate(mWindowImageView);
                mWindowImageView = null;
            }
        });
    }

    private void addWindowAlert(){
        if(mWindowImageView != null){
            return;
        }
        mWindowImageView = new ImageView(this);
        mWindowImageView.setImageResource(R.drawable.cat);

        //type 应用 Window 、子Window 和系统 Window
        // 应用 Window 的层级范围： 1 ~ 99
        // 子 Window 的层级范围： 1000 ~ 1999
        //系统 Window 的层级范围： 2000 ~ 2999

        // flag表示window的显示特性 FLAG_NOT_FOCUSABLE 表示不需要获取焦点，不接受各种输入事件
        // FLAG_NOT_TOUCH_MODAL 最终事件会直接传递给下层具有焦点的 Window
        // 自己 Window 区域内的事件自己处理：自己 Window 区域外的事件传递给底层 Window
        // 可以让此 Window 显示在锁屏上

        WindowManager.LayoutParams mWindowLayoutParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                2099,
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
                PixelFormat.TRANSPARENT
        );

        if(Build.VERSION.SDK_INT >= 26) {
            mWindowLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            mWindowLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }

        mWindowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
        mWindowLayoutParams.x = 0;
        mWindowLayoutParams.y = 300;


        mWindowImageView.setOnTouchListener((v1, event) -> {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mLastX = (int) event.getRawX();
                    mLastY = (int) event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    int mInScreenX = (int) event.getRawX();
                    int mInScreenY = (int) event.getRawY();
                    mWindowLayoutParams.x = mWindowLayoutParams.x + mInScreenX - mLastX;
                    mWindowLayoutParams.y = mWindowLayoutParams.y + mInScreenY - mLastY;
                    mWindowManager.updateViewLayout(mWindowImageView, mWindowLayoutParams);
                    mLastX = mInScreenX;
                    mLastY = mInScreenY;
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                default:
                    break;
            }
            return false;
        });
        mWindowManager.addView(mWindowImageView, mWindowLayoutParams);
    }

    /**
     * @param childView
     */
    private void initBMView(View childView) {
        ImageView iv = childView.findViewById(R.id.iv);
        final Bitmap bitmap = BitmapUtil.decodeBitmapFromResource(getResources(), R.drawable.scenery, 100, 100);
        iv.setImageBitmap(bitmap);
    }

    /**
     * 图片着色器的使用
     *
     * @param childView
     */
    private void initBitmapShaderView(View childView) {
        Button btnRepeat = childView.findViewById(R.id.btn_repeat);
        Button btnClamp = childView.findViewById(R.id.btn_clamp);
        Button btnMirror = childView.findViewById(R.id.btn_mirror);
        BitmapShaderView bsvShader = childView.findViewById(R.id.bsv_shader);
        btnRepeat.setOnClickListener(v -> {
            bsvShader.setShader(Shader.TileMode.REPEAT);
        });
        btnClamp.setOnClickListener(v -> {
            bsvShader.setShader(Shader.TileMode.CLAMP);
        });
        btnMirror.setOnClickListener(v -> {
            bsvShader.setShader(Shader.TileMode.MIRROR);
        });
    }

    /**
     * 动态矢量图的使用
     *
     * @param childView
     */
    private void initVectorLine(View childView) {
        ImageView img = childView.findViewById(R.id.img);
        AnimatedVectorDrawableCompat vectorDrawableCompat = null;
        if (position == 41) {
            vectorDrawableCompat = AnimatedVectorDrawableCompat.create(this, R.drawable.line_animated_vector);
        } else if (position == 42) {
            vectorDrawableCompat = AnimatedVectorDrawableCompat.create(this, R.drawable.search_animated_vector);
        }
        img.setImageDrawable(vectorDrawableCompat);
        ((Animatable) img.getDrawable()).start();

    }

    private void initForegroundColorView(View childView) {
        TextView tv = childView.findViewById(R.id.tv);
        MutableForegroundColorSpan foregroundColorSpan = new MutableForegroundColorSpan(255, Color.BLACK);
        ObjectAnimator animator = ObjectAnimator.ofInt(foregroundColorSpan, "foregroundColor", Color.BLACK, Color.RED);
        SpannableString ss = new SpannableString("好好学习,天天向上");
        animator.addUpdateListener(animation -> {
            ss.setSpan(foregroundColorSpan, 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            tv.setText(ss);
        });
        animator.setRepeatCount(Animation.INFINITE);
        animator.setEvaluator(new ArgbEvaluator());
        animator.setDuration(1000);
        animator.start();

    }


    /**
     * • APPEARING ：元素在容器中出现时所定义的动画。
     * • DISAPPEARING 元素在容器中消失时所定义的动画
     * • CHANGE APPEARING 由于容器中要显现个新的元素 需要变化的元素所应用的动画
     * • CHANGE DISAPPEARING 当容器中某个元素消失时 其他需要变化的元素所应用的动画。
     *
     * @param childView
     */
    private void initLayoutTransition(View childView) {
        Button btnAdd = childView.findViewById(R.id.btn_add);
        Button btnRemove = childView.findViewById(R.id.btn_remove);
        LinearLayout llContainer = childView.findViewById(R.id.ll_container);
        LayoutTransition transition = new LayoutTransition();

        ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f, 0f);
        transition.setAnimator(LayoutTransition.APPEARING, animIn);

        ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);
        transition.setAnimator(LayoutTransition.DISAPPEARING, animOut);

        llContainer.setLayoutTransition(transition);

        transition.addTransitionListener(new LayoutTransition.TransitionListener() {
            @Override
            public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
                Log.i(TAG, "startTransition: transitionType = " + transitionType + ", count = " + container.getChildCount()
                        + " view = " + view.getClass().getName());
            }

            @Override
            public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
                Log.i(TAG, "endTransition: transitionType = " + transitionType + ", count = " + container.getChildCount()
                        + " view = " + view.getClass().getName());
            }
        });
        btnAdd.setOnClickListener(view -> {
            addBtnView(llContainer);
        });

        btnRemove.setOnClickListener(view -> {
            removeBtnView(llContainer);
        });
    }


    private void initAnimateLayoutChanges(View childView) {
        Button btnAdd = childView.findViewById(R.id.btn_add);
        Button btnRemove = childView.findViewById(R.id.btn_remove);
        LinearLayout llContainer = childView.findViewById(R.id.ll_container);
        btnAdd.setOnClickListener(view -> {
            addBtnView(llContainer);
        });

        btnRemove.setOnClickListener(view -> {
            removeBtnView(llContainer);
        });
    }

    private void addBtnView(LinearLayout llContainer) {
        i++;
        Button b = new Button(CustomViewActivity.this);
        b.setText("button" + i);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        b.setLayoutParams(lp);
        llContainer.addView(b, 0);
    }

    private void removeBtnView(LinearLayout llContainer) {
        if (i > 0) {
            llContainer.removeViewAt(0);
            i--;
        }
    }

    private void initKeyFrameView(View childView) {
        ImageView img = childView.findViewById(R.id.img);
        Button btn = childView.findViewById(R.id.btn);
        Button btn2 = childView.findViewById(R.id.btn2);
        Button btn3 = childView.findViewById(R.id.btn3);
        btn.setOnClickListener(view -> {
            Keyframe frame0 = Keyframe.ofFloat(0f, 0);
            Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
            Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f);
            Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f);
            Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f);
            Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f);
            Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f);
            Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f);
            Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f);
            Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f);
            Keyframe frame10 = Keyframe.ofFloat(1.0f, 0);
            PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation", frame0, frame1, frame2, frame3,
                    frame4, frame5, frame6, frame7, frame8, frame9, frame10);
            ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(img, frameHolder);
            animator.setDuration(1000);
            animator.start();
        });

        btn2.setOnClickListener(view -> {
            Keyframe frame0 = Keyframe.ofFloat(0f, 0);
            Keyframe frame1 = Keyframe.ofFloat(0.5f, -20f);
            Keyframe frame2 = Keyframe.ofFloat(1.0f);
            frame2.setValue(0);
            PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation", frame0, frame1, frame2);
            ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(img, frameHolder);
            animator.setDuration(1000);
            animator.start();
        });

        btn3.setOnClickListener(view -> {
            Keyframe frame0 = Keyframe.ofFloat(0f, 0);
            Keyframe frame1 = Keyframe.ofFloat(0.5f, -20f);
            Keyframe frame2 = Keyframe.ofFloat(1.0f);
            frame2.setValue(0);
            frame2.setInterpolator(new BounceInterpolator());
            PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation", frame0, frame1, frame2);
            ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(img, frameHolder);
            animator.setDuration(1000);
            animator.start();
        });
    }


    /**
     * 通过PropertyValuesHolder设置ObjectAnimator
     *
     * @param childView
     */
    private void initPropertyValuesHolder(View childView) {
        Button btn = childView.findViewById(R.id.btn);
        MyTextView tv = childView.findViewById(R.id.tv);
        btn.setOnClickListener(v -> {
            if (position == 26) {
                PropertyValuesHolder rotationPropertyValuesHolder = PropertyValuesHolder.ofFloat("rotation", 60f, -60f, 40f, -40f, -20f, 20f, 10f, -10f, 0f);
                PropertyValuesHolder alphaPropertyValuesHolder = PropertyValuesHolder.ofFloat("alpha", 0.1f, 1f, 0.1f, 1f);
                ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(tv, rotationPropertyValuesHolder, alphaPropertyValuesHolder);
                animator.setDuration(3000);
                animator.start();
            } else {
                PropertyValuesHolder valuesHolder = PropertyValuesHolder.ofObject("charText", new CharEvaluator(), Character.valueOf('A'), Character.valueOf('Z'));
                ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(tv, valuesHolder);
                animator.setDuration(3000);
                animator.setInterpolator(new AccelerateDecelerateInterpolator());
                animator.start();
            }
        });
    }

    /**
     * 通过xml使用valueAnimator，objAnimator
     *
     * @param childView
     */
    private void initValueAnimatorView(View childView) {
        Button btn = childView.findViewById(R.id.btn);
        TextView tv = childView.findViewById(R.id.tv);
        btn.setOnClickListener(v -> {
            //使用AnimatorInflater加载对应的Animator
            if (position == 24) {
                ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.valueanim);
                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        int curValue = (int) animation.getAnimatedValue();
                        tv.layout(curValue, curValue, curValue + tv.getWidth(), curValue + tv.getWidth());
                    }
                });
                animator.start();
            } else {
                ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.objectanim);
                //将动画效果设置到tv
                objectAnimator.setTarget(tv);
                objectAnimator.start();
            }
        });
    }

    /**
     * 路径动画
     *
     * @param childView
     */
    private void initMenuView(View childView) {
        menu = childView.findViewById(R.id.menu);
        item1 = childView.findViewById(R.id.item1);
        item2 = childView.findViewById(R.id.item2);
        item3 = childView.findViewById(R.id.item3);
        item4 = childView.findViewById(R.id.item4);
        item5 = childView.findViewById(R.id.item5);

        menu.setOnClickListener(v -> {
            clickMenu();
        });

        item1.setOnClickListener(v -> {
            clickMenu();
        });

        item2.setOnClickListener(v -> {
            clickMenu();
        });

        item3.setOnClickListener(v -> {
            clickMenu();
        });

        item4.setOnClickListener(v -> {
            clickMenu();
        });
        item5.setOnClickListener(v -> {
            clickMenu();
        });
    }

    private void clickMenu() {
        if (!mIsOpenMenu) {
            mIsOpenMenu = true;
            openMenu();
        } else {
            mIsOpenMenu = false;
            closeMenu();
        }
    }

    private void closeMenu() {
        doAnimateClose(item1, 0, 5, 300);
        doAnimateClose(item2, 1, 5, 300);
        doAnimateClose(item3, 2, 5, 300);
        doAnimateClose(item4, 3, 5, 300);
        doAnimateClose(item5, 4, 5, 300);
    }

    private void openMenu() {
        doAnimateOpen(item1, 0, 5, 300);
        doAnimateOpen(item2, 1, 5, 300);
        doAnimateOpen(item3, 2, 5, 300);
        doAnimateOpen(item4, 3, 5, 300);
        doAnimateOpen(item5, 4, 5, 300);
    }

    private void doAnimateOpen(ImageView item, int index, int total, int radius) {
        if (item.getVisibility() != View.VISIBLE) {
            item.setVisibility(View.VISIBLE);
        }
        double degree = Math.toDegrees(90) / (total - 1) * index;
        //计算平移距离
        int translationX = -(int) (radius * Math.sin(degree));
        int translationY = -(int) (radius * Math.cos(degree));

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(
                ObjectAnimator.ofFloat(item, "translationX", 0, translationX),
                ObjectAnimator.ofFloat(item, "translationY", 0, translationY),
                ObjectAnimator.ofFloat(item, "scaleX", 0, 1.0f),
                ObjectAnimator.ofFloat(item, "scaleY", 0, 1.0f),
                ObjectAnimator.ofFloat(item, "alpha", 0, 1.0f)
        );
        animatorSet.setDuration(500).start();
    }

    private void doAnimateClose(ImageView item, int index, int total, int radius) {
        if (item.getVisibility() != View.VISIBLE) {
            item.setVisibility(View.VISIBLE);
        }
        double degree = Math.toDegrees(90) / (total - 1) * index;
        //计算平移距离
        int translationX = -(int) (radius * Math.sin(degree));
        int translationY = -(int) (radius * Math.cos(degree));

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(
                ObjectAnimator.ofFloat(item, "translationX", translationX, 0),
                ObjectAnimator.ofFloat(item, "translationY", translationY, 0),
                ObjectAnimator.ofFloat(item, "scaleX", 1.0f, 0),
                ObjectAnimator.ofFloat(item, "scaleY", 1.0f, 0),
                ObjectAnimator.ofFloat(item, "alpha", 1.0f, 0)
        );
        animatorSet.setDuration(500).start();
    }


    /**
     * 学习使用AnimatorSet
     *
     * @param childView
     */
    private void initAnimateSetView(View childView) {
        Button btn = childView.findViewById(R.id.btn);
        TextView mTvl = childView.findViewById(R.id.tv1);
        TextView mTv2 = childView.findViewById(R.id.tv2);

        btn.setOnClickListener(v -> {
            ObjectAnimator tvlBgAnimator = ObjectAnimator.ofInt(mTvl, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
            tvlBgAnimator.setDuration(2000);
            tvlBgAnimator.setStartDelay(1000);
//            tvlBgAnimator.setRepeatCount(ValueAnimator.INFINITE);

            ObjectAnimator tv1TranslateY = ObjectAnimator.ofFloat(mTvl, "translationY", 0, 300, 0);
            tv1TranslateY.setDuration(5000);
            tv1TranslateY.setInterpolator(new BounceInterpolator());
            tv1TranslateY.setStartDelay(2000);
//            tv1TranslateY.setRepeatCount(ValueAnimator.INFINITE);

            ObjectAnimator tv2TranslateY = ObjectAnimator.ofFloat(mTv2, "translationY", 0, 400, 0);
            tv2TranslateY.setStartDelay(1000);
//            tv2TranslateY.setRepeatCount(ValueAnimator.INFINITE);

            AnimatorSet animatorSet = new AnimatorSet();
            //有序的播放动画
//            animatorSet.playSequentially(tvlBgAnimator,tv1TranslateY,tv2TranslateY);

            //同时开始执行动画
//            animatorSet.playTogether(tvlBgAnimator,tv1TranslateY,tv2TranslateY);


            //使用builder构建顺序或者同时执行动画
            AnimatorSet.Builder builder = animatorSet.play(tv1TranslateY).with(tv2TranslateY).after(tvlBgAnimator);
            //如果动画设置了插值器或者时间，但是animatorSet也设置了插值器或者时间，会覆盖原来动画的时间和插值器。
            animatorSet.setDuration(1000);

            //这个延迟执行不会覆盖原来的动画的延迟时间。  会叠加。
            animatorSet.setStartDelay(2000);
            animatorSet.setInterpolator(new LinearInterpolator());
            animatorSet.start();

        });
    }

    /**
     * ObjectAnimator实现抛物球动画示例
     *
     * @param childView
     */
    private void initObjectBallView(View childView) {
        Button btn = childView.findViewById(R.id.btn);
        BallTextView tv = childView.findViewById(R.id.tv);
        btn.setOnClickListener(v -> {
            ObjectAnimator animator = ObjectAnimator.ofObject(tv, "FallingPoint", new FallingBallEvaluator(), new Point(0, 0), new Point(500, 500));
            animator.setDuration(1500);
            animator.start();
        });
    }

    /**
     * 抛物球动画示例
     *
     * @param childView
     */
    private void initBallView(View childView) {
        Button btn = childView.findViewById(R.id.btn);
        TextView tv = childView.findViewById(R.id.tv);
        btn.setOnClickListener(v -> {
            ValueAnimator animator = ValueAnimator.ofObject(new FallingBallEvaluator(), new Point(0, 0), new Point(500, 500));
            animator.setDuration(1500);
//            animator.setInterpolator(new AccelerateDecelerateInterpolator());
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    Point point = (Point) animation.getAnimatedValue();
                    tv.layout(point.x, point.y, point.x + tv.getWidth(), point.y + tv.getHeight());
                }
            });
            animator.start();
        });
    }

    /**
     * 学习使用ObjectAnimateView
     *
     * @param childView
     */
    private void initObjectAnimateView(View childView) {
        Button btn = childView.findViewById(R.id.btn);
        TextView tv = childView.findViewById(R.id.tv);
        btn.setOnClickListener(v -> {
            //参数一： 操作哪个控件  参数二： 控件的某个属性 注意是调用了setXXX方法 参数三： 可变值
//            ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "alpha", 1, 0, 1);
//            animator.setDuration(1000);
//            animator.start();

//            ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "rotation", 0, 180, 0);
//            animator.setDuration(2000);
//            animator.start();

//            ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "rotationX", 0, 180, 0);
//            animator.setDuration(2000);
//            animator.start();

            ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "rotationY", 0, 180, 0);
            animator.setDuration(2000);
            animator.start();

        });
    }

    /**
     * 学习使用ValueAnimator
     *
     * @param childView
     */
    private void initValueAnimateView(View childView) {
        Button btn = childView.findViewById(R.id.btn);
        TextView tv = childView.findViewById(R.id.tv);
        btn.setOnClickListener(v -> {
//            ValueAnimator animator = ValueAnimator.ofInt(0, 400);
//            ValueAnimator animator = ValueAnimator.ofFloat(0f, 400f, 50f, 300f);
//            ValueAnimator animator = ValueAnimator.ofInt(0xffffff00, 0xff0000ff);
            ValueAnimator animator = ValueAnimator.ofObject(new CharEvaluator(), 'A', 'Z');
            animator.setDuration(1000);
            //设置加速减速插值器
            animator.setInterpolator(new AccelerateDecelerateInterpolator());

//            animator.setRepeatCount(3);
            //设置自定义插值器
//            animator.setInterpolator(new MyInterpolator());

            //设置自定义转换器
//            animator.setEvaluator(new MyEvaluator());

            //设置使用颜色转换器
//            animator.setEvaluator(new ArgbEvaluator());
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
//                    int currentValue = (int) animation.getAnimatedValue();
//                    Float floatValue = (Float) animation.getAnimatedValue();
//                    int currentValue = floatValue.intValue();
//                    Log.i(TAG, "onAnimationUpdate: currentValue = " + currentValue);
//                    tv.layout(currentValue, currentValue, currentValue + tv.getWidth(), currentValue+ tv.getHeight());

//                    int currentValue = (Integer) animation.getAnimatedValue();
//                    tv.setBackgroundColor(currentValue);

                    Character currentValue = (Character) animation.getAnimatedValue();
                    tv.setText(currentValue.toString());
                }
            });
            animator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
                    Log.i(TAG, "onAnimationStart: ");
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    Log.i(TAG, "onAnimationEnd: ");
                }

                @Override
                public void onAnimationCancel(Animator animation) {
                    Log.i(TAG, "onAnimationCancel: ");
                }

                @Override
                public void onAnimationRepeat(Animator animation) {
                    Log.i(TAG, "onAnimationRepeat: ");
                }
            });
            animator.start();
        });
    }

    /**
     * 学习帧动画
     *
     * @param childView
     */
    private void initFrameView(View childView) {
        ImageView frame_image = childView.findViewById(R.id.frame_image);
        Button btn_start = childView.findViewById(R.id.btn_start);
        Button btn_end = childView.findViewById(R.id.btn_end);
        AnimationDrawable animationDrawable = (AnimationDrawable) frame_image.getDrawable();
        btn_start.setOnClickListener(v -> {
            animationDrawable.start();
        });
        btn_end.setOnClickListener(v -> {
            animationDrawable.stop();
        });
    }


    private void initScannerView(View childView) {
        TextView start_scan = childView.findViewById(R.id.start_scan);
        ImageView circle1 = childView.findViewById(R.id.circle1);
        ImageView circle2 = childView.findViewById(R.id.circle2);
        ImageView circle3 = childView.findViewById(R.id.circle3);
        ImageView circle4 = childView.findViewById(R.id.circle4);
        Animation animation1 = AnimationUtils.loadAnimation(this, R.anim.scale_alpha_anim);
        Animation animation2 = AnimationUtils.loadAnimation(this, R.anim.scale_alpha_anim);
        Animation animation3 = AnimationUtils.loadAnimation(this, R.anim.scale_alpha_anim);
        Animation animation4 = AnimationUtils.loadAnimation(this, R.anim.scale_alpha_anim);
        start_scan.setOnClickListener(v -> {
            circle1.startAnimation(animation1);

            //设置延迟时间
            animation2.setStartOffset(600);
            circle2.startAnimation(animation2);

            animation3.setStartOffset(1200);
            circle3.startAnimation(animation3);

            animation4.setStartOffset(1800);
            circle4.startAnimation(animation4);
        });

    }

    private void initLoadingView(View childView) {
        ImageView img = childView.findViewById(R.id.loading);
        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setRepeatCount(Animation.INFINITE);
        rotateAnimation.setDuration(3000);
        rotateAnimation.setInterpolator(new LinearInterpolator());
        img.startAnimation(rotateAnimation);
    }

    private void initSplashView(View childView) {
        ImageView img = childView.findViewById(R.id.img);
        ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.2f, 1.0f, 1.2f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        scaleAnimation.setDuration(6000);
        scaleAnimation.setFillAfter(true);
        img.startAnimation(scaleAnimation);
    }

    private void initAnimateView(View childView) {
        Button btn = childView.findViewById(R.id.btn);
        TextView tv = childView.findViewById(R.id.tv);
        btn.setOnClickListener(v -> {
            if (position == 7) {
                Animation animation = AnimationUtils.loadAnimation(this, R.anim.scaleanim);
                animation.setDuration(700);
                animation.setRepeatCount(Animation.INFINITE); //循环次数无限循环
                animation.setRepeatMode(Animation.REVERSE); //倒序回放
                tv.startAnimation(animation);
            } else if (position == 8) {
                Animation animation = AnimationUtils.loadAnimation(this, R.anim.alphaanim);
                animation.setDuration(700);
                animation.setFillBefore(true); //保持动画的开始状态
                tv.startAnimation(animation);
            } else if (position == 9) {
                Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotateanim);
                animation.setDuration(700);
                animation.setFillAfter(true); //保持动画的结束状态
                tv.startAnimation(animation);
            } else if (position == 10) {
                Animation animation = AnimationUtils.loadAnimation(this, R.anim.translateanim);
                animation.setDuration(700);
                animation.setRepeatCount(Animation.INFINITE);
                tv.startAnimation(animation);
            } else if (position == 11) {
                Animation animation = AnimationUtils.loadAnimation(this, R.anim.setanim);
                tv.startAnimation(animation);
            } else if (position == 12) {
                RotateAnimation rotateAnimation = new RotateAnimation(0, -650, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                rotateAnimation.setDuration(3000);
                rotateAnimation.setFillAfter(true);

                ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                scaleAnimation.setDuration(700);
                scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                        Log.i(TAG, "scaleAnimation onAnimationStart: ");
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        Log.i(TAG, "scaleAnimation onAnimationEnd: ");
                        //缩放动画结束后开启旋转动画
                        tv.startAnimation(rotateAnimation);
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                        Log.i(TAG, "scaleAnimation onAnimationRepeat: ");
                    }
                });
                tv.startAnimation(scaleAnimation);
            }
        });
    }
}